#!/usr/bin/env dub --single
/+dub.sdl:
   name "prebuild"
   targetType "executable"
+/

struct Arg
{
   string name;
   string value;
}

Arg parseArg(string arg)
{
   import std.string: split;

   auto parts = arg.split(':');

   return Arg(parts[0][1..$], parts[1]);
}

void replaceContents(string inputFileName, string outputFileName, string[string] values)
{
   import std.file: readText, write;
   import std.string: replace;

   auto content = readText(inputFileName);

   foreach (const ref key, value; values) {
      content = replace(content, key, value);
   }

   write(outputFileName, content);
}

int main(string[] args)
{
   import std.process: environment, execute;
   import std.stdio: stderr;
   import std.string: chomp, strip, split;

   if (args.length < 3) {
      stderr.writefln("error: expected two arguments: -vcs:<vcs.in.d> -config:<config.d.in>");
      return 1;
   }

   const vcsInput = parseArg(args[1]);
   const configInput = parseArg(args[2]);

   const vcsOutput = chomp(vcsInput.value, ".in");
   const configOutput = chomp(configInput.value, ".in");

   const projectVersion = environment.get("DUB_PACKAGE_VERSION");
   if (!projectVersion) {
      stderr.writeln("error: failed to read DUB_PACKAGE_VERSION environment variable.");
      return 1;
   }

   try {
      auto git_rev = execute(["git", "rev-parse", "--short", "HEAD"]);
      if (git_rev.status != 0) {
         replaceContents(vcsInput.value, vcsOutput, ["@VCS_TAG@": "release"]);
      } else {
         replaceContents(vcsInput.value, vcsOutput, ["@VCS_TAG@": strip(git_rev.output)]);
      }
   } catch (Exception) {
      // git isn't installed.
      replaceContents(vcsInput.value, vcsOutput, ["@VCS_TAG@": "release"]);
   }
         

   string[string] conf;
   conf["@PROJECT_VERSION_STRING@"] = projectVersion;

   const versionSplit = projectVersion.split('.');
   const majorVersion = versionSplit[0];
   const minorVersion = versionSplit[1];
   const patchVersion = versionSplit[2];

   conf["@PROJECT_VERSION_MAJOR@"] = majorVersion;
   conf["@PROJECT_VERSION_MINOR@"] = minorVersion;
   conf["@PROJECT_VERSION_PATCH@"] = patchVersion;

   replaceContents(configInput.value, configOutput, conf);

   return 0;
}
